// 引入系统诊断契约和全球化支持
using System.Diagnostics.Contracts;
using System.Globalization;
// 引入坐标值对象，表示玩家在游戏中的位置
using RealtimeCollabGame.Domain.ValueObjects;

namespace RealtimeCollabGame.Domain.Entities;

public class Player : BaseEntity
{
    public string NickName { get; private set; } = string.Empty;
    public string? Avatar { get; private set; }
    public PlayerColor Color { get; private set; } = null!;
    public int TotalGames { get; private set; }
    public int WinCount { get; private set; }
    public bool IsOnline { get; private set; }
    public DateTime? LastActiveAt { get; private set; }
    public bool IsReady { get; private set; }
    public bool IsHost { get; private set; }
    public int AreaCount { get; private set; }

    private Player() { }

    public Player(string nickName, string? avatar = null, bool isHost = false)
    {
        NickName = nickName ?? throw new ArgumentNullException(nameof(nickName));
        Avatar = avatar;
        Color = PlayerColor.GetRandomColor();
        TotalGames = 0;
        WinCount = 0;
        IsOnline = true;
        LastActiveAt = DateTime.UtcNow;
        IsHost = isHost;
        AreaCount = 0;
    }

    public void UpdateOnlineStatus(bool isOnline)
    {
        IsOnline = isOnline;
        LastActiveAt = DateTime.UtcNow;
        UpdatedAt = DateTime.UtcNow;
    }

    public void IncrementGames()
    {
        TotalGames++;
        UpdatedAt = DateTime.UtcNow;
    }

    public void IncrementWins()
    {
        WinCount++;
        UpdatedAt = DateTime.UtcNow;
    }

    public void UpdateColor(PlayerColor newColor)
    {
        Color = newColor;
        UpdatedAt = DateTime.UtcNow;
    }

    public void SetReady(bool isReady)
    {
        IsReady = isReady;
        UpdatedAt = DateTime.UtcNow;
    }

    public void SetHost(bool isHost)
    {
        IsHost = isHost;
        UpdatedAt = DateTime.UtcNow;
    }

    public void UpdateAreaCount(int areaCount)
    {
        AreaCount = areaCount;
        UpdatedAt = DateTime.UtcNow;
    }

    public double GetWinRate()
    {
        return TotalGames > 0 ? (double)WinCount / TotalGames : 0;
    }
}